﻿using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace Accumulation.Controls.Calendars {

    internal class DateFormatControl : UserControl {

        #region Components of the control

        private ComboBox cbFormat;
        private ComboBox cbSeperator;
        private CheckBox cbSupportTime;
        private Button btnSubmit;
        private Label label1;
        private Label label2;
        private void InitializeComponent() {
            this.cbFormat = new ComboBox();
            this.cbSeperator = new ComboBox();
            this.cbSupportTime = new CheckBox();
            this.btnSubmit = new Button();
            this.label1 = new Label();
            this.label2 = new Label();
            this.SuspendLayout();
            // 
            // cbFormat
            // 
            this.cbFormat.FormattingEnabled = true;
            this.cbFormat.Items.AddRange(new object[] {
            "年 月 日",
            "月 日 年",
            "日 月 年"});
            this.cbFormat.Location = new System.Drawing.Point(55, 12);
            this.cbFormat.Name = "cbFormat";
            this.cbFormat.Size = new System.Drawing.Size(78, 21);
            this.cbFormat.TabIndex = 0;
            // 
            // cbSeperator
            // 
            this.cbSeperator.FormattingEnabled = true;
            this.cbSeperator.Items.AddRange(new object[] {
            "-",
            ".",
            "/"});
            this.cbSeperator.Location = new System.Drawing.Point(55, 39);
            this.cbSeperator.Name = "cbSeperator";
            this.cbSeperator.Size = new System.Drawing.Size(78, 21);
            this.cbSeperator.TabIndex = 1;
            // 
            // cbSupportTime
            // 
            this.cbSupportTime.AutoSize = true;
            this.cbSupportTime.Location = new System.Drawing.Point(55, 66);
            this.cbSupportTime.Name = "cbSupportTime";
            this.cbSupportTime.Size = new System.Drawing.Size(74, 17);
            this.cbSupportTime.TabIndex = 2;
            this.cbSupportTime.Text = "支持时间";
            this.cbSupportTime.UseVisualStyleBackColor = true;
            // 
            // btnSubmit
            // 
            this.btnSubmit.Location = new System.Drawing.Point(46, 89);
            this.btnSubmit.Name = "btnSubmit";
            this.btnSubmit.Size = new System.Drawing.Size(50, 23);
            this.btnSubmit.TabIndex = 3;
            this.btnSubmit.Text = "确定";
            this.btnSubmit.UseVisualStyleBackColor = true;
            this.btnSubmit.Click += new System.EventHandler(this.btnSubmit_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(15, 15);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(43, 13);
            this.label1.TabIndex = 4;
            this.label1.Text = "格式：";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(3, 42);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(55, 13);
            this.label2.TabIndex = 5;
            this.label2.Text = "分隔符：";
            // 
            // DateFormat
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = AutoScaleMode.Font;
            this.Controls.Add(this.btnSubmit);
            this.Controls.Add(this.cbSupportTime);
            this.Controls.Add(this.cbSeperator);
            this.Controls.Add(this.cbFormat);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Name = "DateFormat";
            this.Size = new System.Drawing.Size(143, 123);
            this.Load += new System.EventHandler(this.DateFormat_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        public event EventHandler CloseDropDownEvent;
        public string Value { get; set; }

        private string _value;

        public DateFormatControl(object value) {
            InitializeComponent();
            this._value = value == null ? string.Empty : value.ToString();
        }

        private void DateFormat_Load(object sender, EventArgs e) {
            string ymdPattern = @"^[y]{4}[-\.\/][M]{2}[-\.\/][d]{2}( [H]{2}:[m]{2})?$";
            string mdyPattern = @"^[M]{2}[-\.\/][d]{2}[-\.\/][y]{4}( [H]{2}:[m]{2})?$";
            string dmyPattern = @"^[d]{2}[-\.\/][M]{2}[-\.\/][y]{4}( [H]{2}:[m]{2})?$";

            int formatIndex = 0;
            string pattern = ymdPattern;
            if (Regex.IsMatch(this._value, ymdPattern)) {
                formatIndex = 0;
                pattern = ymdPattern;
            }
            else if (Regex.IsMatch(this._value, mdyPattern)) {
                formatIndex = 1;
                pattern = mdyPattern;
            }
            else if (Regex.IsMatch(this._value, dmyPattern)) {
                formatIndex = 2;
                pattern = dmyPattern;
            }


            int seperatorIndex = 0;
            if (this._value.Contains('-')) {
                seperatorIndex = 0;
            }
            else if (this._value.Contains('.')) {
                seperatorIndex = 1;
            }
            else if (this._value.Contains('/')) {
                seperatorIndex = 2;
            }

            this.cbFormat.SelectedIndex = formatIndex;
            this.cbSeperator.SelectedIndex = seperatorIndex;
            this.cbSupportTime.Checked = !string.IsNullOrEmpty(Regex.Match(this._value, pattern).Groups[1].Value);
        }

        private void btnSubmit_Click(object sender, EventArgs e) {
            if (this.cbFormat.SelectedIndex == -1 ||
                this.cbSeperator.SelectedIndex == -1) {
                this.cbFormat.SelectedIndex = this.cbSeperator.SelectedIndex = 1;
            }

            string[,] dateFormats = { { "yyyy", "MM", "dd" }, { "MM", "dd", "yyyy" }, { "dd", "MM", "yyyy" } };
            string[] datetimeFormats = { "HH", "mm" };
            char[] seperators = { '-', '.', '/' };

            int formatIndex = this.cbFormat.SelectedIndex;
            int seperatorIndex = this.cbSeperator.SelectedIndex;
            bool supportTimeFlag = this.cbSupportTime.Checked;

            string result = string.Empty;
            for (int i = 0; i < 3; i++) {
                result += dateFormats[formatIndex, i] + seperators[seperatorIndex];
            }
            result = result.TrimEnd(seperators[seperatorIndex]);
            if (supportTimeFlag) {
                result += " ";
                foreach (string s in datetimeFormats) {
                    result += s + ":";
                }
                result = result.TrimEnd(':');
            }

            this.Value = result;
            this.CloseDropDownEvent(null, EventArgs.Empty);
        }
    }

    internal class DateFormatConveter : TypeConverter {
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
            return typeof(string) == destinationType;
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
            if (destinationType == typeof(string) && value != null) {
                string val = value.ToString();
                string ymdPattern = @"^[y]{4}[-\.\/][M]{2}[-\.\/][d]{2}( [H]{2}:[m]{2})?$";
                string mdyPattern = @"^[M]{2}[-\.\/][d]{2}[-\.\/][y]{4}( [H]{2}:[m]{2})?$";
                string dmyPattern = @"^[d]{2}[-\.\/][M]{2}[-\.\/][y]{4}( [H]{2}:[m]{2})?$";

                bool ymdFlag = Regex.IsMatch(val, ymdPattern);
                bool mdyFlag = Regex.IsMatch(val, mdyPattern);
                bool dmyFlag = Regex.IsMatch(val, dmyPattern);

                if (ymdFlag || mdyFlag || dmyFlag) {
                    return value;
                }
            }
            return "yyyy-MM-dd";
        }
    }

    internal class DateFormatEditor : UITypeEditor {
        private IWindowsFormsEditorService _edSvc;

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
            return UITypeEditorEditStyle.DropDown;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {
            this._edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (this._edSvc != null) {
                DateFormatControl dfc = new DateFormatControl(value);
                dfc.CloseDropDownEvent += dfc_CloseDropDownEvent;
                this._edSvc.DropDownControl(dfc);
                value = dfc.Value;
            }
            return value;
        }

        void dfc_CloseDropDownEvent(object sender, EventArgs e) {
            this._edSvc.CloseDropDown();
        }
    }
}
